
/*
MSAA Demo

*DEVELOPED ON VC2010
*CREATED BY beitang@05/17/2011

we dont have to load oleacc dynamically 'cause the latest 
Windows SDK is by default installed along with vc2010.

Usage:
1,start a new IE instance.
2,goto http://www.baidu.com
3,run me and then take a look
*/

#pragma comment(lib, "Oleacc.lib")
#pragma comment(lib, "comsupp.lib")

#include <Windows.h>
#include <Oleacc.h>
#include <mshtml.h>
#include <atlbase.h>
#include <Exdisp.h>
#include <comutil.h>

static const WCHAR* _ieFrameClass = L"IEFrame";
static const WCHAR*	_ieServerClass = L"Internet Explorer_Server";
static const WCHAR*	_magicWindowsMessage = L"WM_HTML_GETOBJECT";
static const WCHAR* _siteToInfiltrate = L"www.baidu.com";
static const CComBSTR js0(
			L"document.getElementById('site-nav').style.display=\"none\";\
			  document.getElementById('J_CategoryHover').style.display=\"none\";");

static const CComBSTR js1(
			L"document.getElementById('lg').innerHTML=\
			 '<img src=\"http://tomcat.apache.org/images/tomcat.gif\"\
			 width=\"270\" height=\"129\" usemap=\"#mp\"/>';");

void analyzeIeWindow(HWND hwnd)
{
	LRESULT lRes;
	CComPtr<IHTMLDocument2> dom; 
	CComPtr<IWebBrowser> pwb; 
	HRESULT hr;

	UINT nMsg = RegisterWindowMessage(_magicWindowsMessage);
    SendMessageTimeout(hwnd, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes);

	hr = ObjectFromLresult(lRes, IID_IHTMLDocument2, 0, (void**)&dom);
	if(!SUCCEEDED(hr)) {
		MessageBox(NULL, L"!!!IID_IHTMLDocument2", L"err", 0);
		return;
	}

	USES_CONVERSION;
	CComBSTR domain(100);
	CComPtr<IHTMLElement> htmBody;
	CComPtr<IDispatch> bodyChildren;
	CComPtr<IHTMLElementCollection> imgColl;
	CComQIPtr<IHTMLWindow2> htmWin;
	CComVariant v;

	dom->get_domain(&domain);
	if(domain == _siteToInfiltrate) {
		MessageBox(NULL, L"target detected~\n now have a look...", L"msg", 0);
		dom->get_body(&htmBody);
		//Execute js
		CComBSTR jsToExecute = 
			L"document.getElementById('lg').innerHTML=\
			 '<img src=\"http://tomcat.apache.org/images/tomcat.gif\"\
			 width=\"270\" height=\"129\" usemap=\"#mp\"/>';";
		dom->get_parentWindow(&htmWin);
		hr = htmWin->execScript(jsToExecute, L"javascript", &v);
	}
}

bool sameWindowClass(HWND hwnd, const WCHAR* targetClass)
{
	if (!IsWindowVisible(hwnd) || !IsWindowEnabled(hwnd)) {
        return false;
    }

	wchar_t className[100];
	ZeroMemory(className, 100*sizeof(WCHAR));
	GetClassName(hwnd, className, 100); 
	if (wcsicmp(targetClass, className) == 0) {
		return true;
	}
	return false;
}

BOOL CALLBACK enumChildProc(
  __in  HWND hwnd,
  __in  LPARAM lParam
)
{
	if(sameWindowClass(hwnd, _ieServerClass)) {
		analyzeIeWindow(hwnd);
		OutputDebugStringW(L"#an_IE_server_window_has_been_located.");
	}
	return TRUE;
}

BOOL CALLBACK enumWindowsProc(
  __in  HWND hwnd,
  __in  LPARAM lParam
)
{
	if (sameWindowClass(hwnd, _ieFrameClass))
	{
		EnumChildWindows(hwnd, enumChildProc, NULL);
		OutputDebugStringW(L"#an_IE_frame_window_has_been_located.");
	}

	return TRUE;
}

/*Main Entry*/
int CALLBACK WinMain(
  __in  HINSTANCE hInstance,
  __in  HINSTANCE hPrevInstance,
  __in  LPSTR lpCmdLine,
  __in  int nCmdShow
)
{
	CoInitialize(NULL);
	EnumWindows(enumWindowsProc, NULL);
	CoUninitialize();
	return 0;
}
